package com.gitee.wsl.compose.ui.richtext.edit.model.span.ext

import androidx.compose.ui.util.fastForEach
import androidx.compose.ui.util.fastForEachReversed
import com.gitee.wsl.compose.ui.richtext.edit.annotation.ExperimentalRichTextApi
import com.gitee.wsl.compose.ui.richtext.edit.model.span.RichSpan
import com.gitee.wsl.compose.ui.richtext.edit.model.span.style.Image


/**
 * Trim the start of the rich span
 *
 * @return True if the rich span is empty after trimming, false otherwise
 */
@OptIn(ExperimentalRichTextApi::class)
internal fun RichSpan.trimStart(): Boolean {
    if (richSpanStyle is Image)
        return false

    if (isBlank()) {
        text = ""
        children.clear()
        return true
    }

    text = text.trimStart()

    if (text.isNotEmpty())
        return false

    var isEmpty = true
    val toRemoveIndices = mutableListOf<Int>()

    for (i in children.indices) {
        val richSpan = children[i]

        val isChildEmpty = richSpan.trimStart()

        if (isChildEmpty) {
            // Remove the child if it's empty
            toRemoveIndices.add(i)
        } else {
            isEmpty = false
            break
        }
    }

    toRemoveIndices.fastForEachReversed {
        children.removeAt(it)
    }

    return isEmpty
}

@OptIn(ExperimentalRichTextApi::class)
internal fun RichSpan.trimEnd(): Boolean {
    val isImage = richSpanStyle is Image

    if (isImage)
        return false

    val isChildrenBlank = isChildrenBlank() && !isImage

    if (text.isBlank() && isChildrenBlank) {
        text = ""
        children.clear()
        return true
    }

    if (isChildrenBlank) {
        children.clear()
        text = text.trimEnd()
        return false
    }

    var isEmpty = true
    val toRemoveIndices = mutableListOf<Int>()

    for (i in children.indices.reversed()) {
        val richSpan = children[i]

        val isChildEmpty = richSpan.trimEnd()

        if (isChildEmpty) {
            // Remove the child if it's empty
            toRemoveIndices.add(i)
        } else {
            isEmpty = false
            break
        }
    }

    toRemoveIndices.fastForEach {
        children.removeAt(it)
    }

    return isEmpty
}